package com.dhcc.autoconfigure;

import com.dhcc.core.ObsService;
import com.dhcc.provider.MinioObsService;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ProjectName Dhcc-Cloud
 * @PackageName com.dhcc.autoconfigure
 * @Title ObsAutoConfiguration
 * @Date 2025/6/8 02:52
 * @Author LiuGuoting
 */
@Data
@Slf4j
@Configuration
@EnableConfigurationProperties(ObsProperties.class)
@ConditionalOnClass({ObsService.class, MinioClient.class})
public class ObsAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "minio", name = "url")
    public MinioClient buildMinioClient(ObsProperties obsProperties) {
        log.info("开始初始化MinioClient, url为{}, accessKey为:{}", obsProperties.getUrl(), obsProperties.getAccessKey());
        MinioClient minioClient = MinioClient
                .builder()
                .endpoint(obsProperties.getUrl())
                .credentials(obsProperties.getAccessKey(), obsProperties.getSecretKey())
                .build();

        minioClient.setTimeout(
                obsProperties.getConnectTimeout(),
                obsProperties.getWriteTimeout(),
                obsProperties.getReadTimeout()
        );
        // Start detection
        String bucketName = obsProperties.getBucket();
        log.info("开始检测文件桶[{}]是否存在", bucketName);
        if (!checkBucket(bucketName, minioClient)) {
            log.info("文件桶[{}]不存在, 开始检查是否可以新建桶", bucketName);
            if (obsProperties.isCreateBucket()) {
                log.info("createBucket为{},开始新建文件桶", obsProperties.isCreateBucket());
                createBucket(bucketName, minioClient);
            }
            else {
                throw new RuntimeException("文件桶["+bucketName+"]不存在, 且未开启新建桶功能（createBucket为false）, 请检查配置或手动新建文件桶");
            }
        }
        else {
            log.info("文件桶[{}]已存在, minio客户端连接成功!", bucketName);
        }

        return minioClient;
    }

    /**
     * 检查桶是否存在
     * @param bucketName
     * @param minioClient
     * @return
     */
    private boolean checkBucket(String bucketName, MinioClient minioClient) {
        boolean isExists = false;
        try {
            isExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            throw new RuntimeException("未能检查桶是否存在", e);
        }
        return isExists;
    }

    /**
     * 创建桶
     * @param bucketName
     * @param minioClient
     */
    private void createBucket(String bucketName, MinioClient minioClient) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            log.info("文件桶[{}]新建成功, minio客户端已连接", bucketName);
        } catch (Exception e) {
            throw new RuntimeException("无法创建默认存储桶", e);
        }
    }
}